package com.ruoyi.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.app.domain.bo.AppUserBagBo;
import com.ruoyi.app.domain.vo.AppTaskVo;
import com.ruoyi.app.domain.vo.AppUserBagVo;
import com.ruoyi.app.service.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.TaskConstants;
import com.ruoyi.common.enums.BillType;
import com.ruoyi.common.enums.CoinType;
import com.ruoyi.common.enums.DetailType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.redis.RedisUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.data.annotation.Transient;
import org.springframework.stereotype.Service;
import com.ruoyi.app.domain.bo.AppUserSignBo;
import com.ruoyi.app.domain.vo.AppUserSignVo;
import com.ruoyi.app.domain.AppUserSign;
import com.ruoyi.app.mapper.AppUserSignMapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Objects;

/**
 * App用户签到记录Service业务层处理
 *
 * @author ruoyi
 * @date 2023-03-28
 */
@RequiredArgsConstructor
@Service
public class AppUserSignServiceImpl implements IAppUserSignService {

    private final AppUserSignMapper baseMapper;
    private final IAppTaskService appTaskService;
    private final IAppDetailService appDetailService;
    private final IAppAssetService appAssetService;
    private final IAppUserBagService iAppUserBagService;

    /**
     * 查询App用户签到记录
     */
    @Override
    public AppUserSignVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询App用户签到记录列表
     */
    @Override
    public TableDataInfo<AppUserSignVo> queryPageList(AppUserSignBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<AppUserSign> lqw = buildQueryWrapper(bo);
        Page<AppUserSignVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询App用户签到记录列表
     */
    @Override
    public List<AppUserSignVo> queryList(AppUserSignBo bo) {
        LambdaQueryWrapper<AppUserSign> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<AppUserSign> buildQueryWrapper(AppUserSignBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<AppUserSign> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getUserId() != null, AppUserSign::getUserId, bo.getUserId());
        lqw.eq(bo.getDay() != null, AppUserSign::getDay, bo.getDay());
        lqw.eq(bo.getSignTime() != null, AppUserSign::getSignTime, bo.getSignTime());
        return lqw;
    }

    /**
     * 新增App用户签到记录
     */
    @Override
    public Boolean insertByBo(AppUserSignBo bo) {
        AppUserSign add = BeanUtil.toBean(bo, AppUserSign.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }


    /**
     * 新增App用户签到记录
     */
    @Override
    public Boolean insert(AppUserSign add) {
        return baseMapper.insert(add) > 0;
    }

    /**
     * 修改App用户签到记录
     */
    @Override
    public Boolean updateByBo(AppUserSignBo bo) {
        AppUserSign update = BeanUtil.toBean(bo, AppUserSign.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 修改App用户签到记录
     */
    @Override
    public Boolean update(AppUserSign update) {
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(AppUserSign entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除App用户签到记录
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public AppUserSign queryUser(Long userId) {
        LambdaQueryWrapper<AppUserSign> signLambdaQueryWrapper = new LambdaQueryWrapper<>();
        signLambdaQueryWrapper.eq(AppUserSign::getUserId, userId);
        return baseMapper.selectOne(signLambdaQueryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppUserSign userSign(Long userId, long time, AppUserSign appUserSign, Map<Integer, Integer> list) {
        Long nowTime = System.currentTimeMillis();
        //判断昨天是否签到
        long yestTime = time - 24 * 60 * 60 * 1000;
        int day = 1;
        if (Objects.nonNull(appUserSign) && appUserSign.getSignTime() >= yestTime) {
            //昨天已经签到连续签到
            day = appUserSign.getDay() + 1 > 7 ? 1 : appUserSign.getDay() + 1;
            appUserSign.setDay(day);
            appUserSign.setSignTime(nowTime);
            update(appUserSign);
        } else {
            //第一次签到
            if (Objects.isNull(appUserSign)) {
                appUserSign = new AppUserSign();
                appUserSign.setDay(day);
                appUserSign.setSignTime(nowTime);
                appUserSign.setUserId(userId);
                insert(appUserSign);
            } else {
                //昨天没有签到断签
                appUserSign.setDay(day);
                appUserSign.setSignTime(nowTime);
                update(appUserSign);
            }
        }
        //发放签到奖励
        AppUserBagVo appUserBagVo = iAppUserBagService.queryByUserId(userId, Constants.FAIL);
        if (Objects.isNull(appUserBagVo)) {
            AppUserBagBo appUserBag = new AppUserBagBo();
            appUserBag.setNumber(list.get(day));
            appUserBag.setUserId(userId);
            appUserBag.setType("1");
            iAppUserBagService.insertByBo(appUserBag);
        } else {
            appUserBagVo.setNumber(appUserBagVo.getNumber() + list.get(day));
            iAppUserBagService.updateByVo(appUserBagVo);
        }
        //增加签到积分
        String key = TaskConstants.userSignKey + userId;
        Integer count = RedisUtils.getCacheObject(key);
        if (count != null) {
            BigDecimal amount = new BigDecimal(list.get(day));
            appAssetService.addIntegral(userId, amount);
            appDetailService.insert(userId, amount, null, BillType.IN.getCode(), CoinType.INTE.getCode(), DetailType.SCORE.getCode(), TaskConstants.userSign, null);
        } else {
            count = 0;
        }
        RedisUtils.setCacheObject(key, ++count, Duration.ofSeconds(DateUtils.seconds()));
        return appUserSign;
    }
}
